#ifndef SIM_VSS_H
#define SIM_VSS_H

#include "NetworkFw.h"
#include "server-addr-config.h"

class VssNode;

enum VssSessionState {
    VSS_SESSION_STATE_UNCONN,
    VSS_SESSION_STATE_UNLOCATED,
    VSS_SESSION_STATE_LOCATED,
    VSS_SESSION_STATE_PARSING_HEAD,
    VSS_SESSION_STATE_PARSING_CHUNKSIZE,
    VSS_SESSION_STATE_EXTRACTING,
    VSS_SESSION_STATE_ERR,
    VSS_SESSION_STATE_FINISHED,
};

struct VssSession: public Session {
    VssSession (SockNode *node): 
        Session(node), state(VSS_SESSION_STATE_UNCONN), 
        request("\0"), curr_pos(0), end_pos(1316*13160-1)
    {};

    virtual ~VssSession() {}
    int state;
    string request;
    fw_file_size_t curr_pos;
    fw_file_size_t end_pos;
    fw_file_size_t chunklen;
    fw_file_size_t range_end;
    friend class VssNode;
};

class VssNode: public AppNode {
    public:
        VssNode() {}
        void StartStream();
        ~VssNode() {};
    protected:
        virtual Session *ConstructSession(SockNode *sock_node) { 
            return (new VssSession(sock_node)); 
        }
        virtual void HandleRecvMsg(FwAppMsg *msg);
        virtual void HandleConnedMsg(FwAppMsg *msg);
        virtual void HandleSendMsg(FwAppMsg *msg) {}
        void RequestTransfer(VssSession *session);
        void CalcRange(VssSession *session);
        static int GetHttpChunkLen(const char* buf, fw_file_size_t &chunklen) {
            chunklen = 0;
            const char *p = buf + 2;
            const char *pend = buf + 16;
            do {
                if (*p >= '0' && *p <= '9') {
                    chunklen = (chunklen << 4) + (*p - '0');
                } else if (*p >= 'A' && *p <= 'F') {
                    chunklen = (chunklen << 4) + 10 + (*p - 'A');
                } else if (*p >= 'a' && *p <= 'f') {
                    chunklen = (chunklen << 4) + 10 + (*p - 'a');
                } else { 
                    if (*p == '\r' && *(p+1) == '\n' && (p != buf + 2)) {
                        return (int)(p - buf + 2);
                    }
                    throw TNMC_FW_EVENT_CODE_HTTP400;
                }
            } while (++p != pend);
            return 0;
        }
};




#endif

